package com.isunland.managesystem.ui;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.GpsSatellite;
import android.location.GpsStatus;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.provider.Settings;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.text.format.DateFormat;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.RatingBar;
import android.widget.TextView;
import butterknife.BindView;
import butterknife.ButterKnife;
import com.android.volley.VolleyError;
import com.google.gson.Gson;
import com.isunland.managesystem.R;
import com.isunland.managesystem.adapter.AttendanceListAdapter;
import com.isunland.managesystem.adapter.AttendanceListAdapter.Callback;
import com.isunland.managesystem.base.BaseVolleyActivity;
import com.isunland.managesystem.common.ApiConst;
import com.isunland.managesystem.common.VolleyResponse;
import com.isunland.managesystem.entity.AttendanceDetail;
import com.isunland.managesystem.entity.AtttendanceOutline;
import com.isunland.managesystem.entity.CurrentUser;
import com.isunland.managesystem.entity.Success;
import com.isunland.managesystem.utils.FileUtil;
import com.isunland.managesystem.utils.GPSToGCJUtil;
import com.isunland.managesystem.utils.LogUtil;
import com.isunland.managesystem.utils.MyUtils;
import com.isunland.managesystem.utils.ToastUtil;
import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.UUID;
import org.json.JSONException;

/**
 * 离线打卡
 */
public class AttendanceOutlineListFragment extends Fragment implements Callback {
  protected static final String EXTRA_IS_LOGIN =
      "com.isunland.managesystem.ui.AttendanceOutlineListFragment.EXTRA_IS_LOGIN";
  private static final int SIGN_IN = 0;
  private static final int SIGN_OUT = 1;
  private static final int SIGN_KEEP = 2;
  //高德定位
  //public AMapLocationClient mLocationClient;
  //public AMapLocationListener mLocationListener = new MyLocationListener();
  ////声明mLocationOption对象
  //public AMapLocationClientOption mLocationOption = null;
  @BindView(R.id.et_remark_attendanceDetail) EditText mRemark;
  @BindView(R.id.lv_list_outline) ListView mListView;
  @BindView(R.id.bt_sign_in) Button mSignIn;
  @BindView(R.id.bt_sign_out) Button mSignOut;
  @BindView(R.id.bt_sign_keep) Button mSignKeep;
  @BindView(R.id.rb_gps) RatingBar mRatingBar;
  @BindView(R.id.tv_gps) TextView mTvGPS;

  private AttendanceListAdapter mAdapter;
  private ArrayList<AttendanceDetail> mList = new ArrayList<>();
  private ArrayList mOriginalList = new ArrayList<>();
  private BaseVolleyActivity mActivity;
  private File mFile = new File(FileUtil.getExternalDir(), "outline.xinpuda");
  private AlertDialog mGpsDialog;//显示gps是否可用的dialog
  private LocationManager mLocationManager;
  private double mLon = 0.0;//经度
  private double mLat = 0.0; //维度
  private GpsStatus.Listener mGpsListener;
  private LocationListener mLocationListener;
  private String mLocationHint = "无法获取经纬度信息";
  private boolean isLogin;//是否登陆

  public static AttendanceOutlineListFragment newInstance(boolean isLogin) {
    Bundle args = new Bundle();
    args.putBoolean(EXTRA_IS_LOGIN, isLogin);
    AttendanceOutlineListFragment fragment = new AttendanceOutlineListFragment();
    fragment.setArguments(args);

    return fragment;
  }

  @Override public void onCreate(@Nullable Bundle savedInstanceState) {
    isLogin = getArguments().getBoolean(EXTRA_IS_LOGIN, false);
    super.onCreate(savedInstanceState);
  }

  @Nullable @Override
  public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
      @Nullable Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_attendance_outline, container, false);
    setHasOptionsMenu(true);
    mActivity = ((BaseVolleyActivity) getActivity());
    android.support.v7.app.ActionBar actionBar = mActivity.getSupportActionBar();
    if (actionBar != null) {

      actionBar.setDisplayHomeAsUpEnabled(true);
      actionBar.setTitle(R.string.sign_outline);
    }
    ButterKnife.bind(this, view);
    //mListView.setEmptyView(inflater.inflate(R.layout.view_empty,container,false));
    View emptyView = View.inflate(getActivity(), R.layout.view_empty, null);
    TextView emptyHint = (TextView) emptyView.findViewById(R.id.tv_emptyText_emptyView);
    emptyHint.setText("离线打卡数据已全部上传");
    ((ViewGroup) mListView.getParent()).addView(emptyView);

    mListView.setEmptyView(emptyView);
    return view;
  }

  @Override public void onPause() {
    super.onPause();
    showGpsDialog();

    if (!mList.equals(mOriginalList)) {

      FileUtil.writeToFile(mList, mFile);
    }
  }

  @Override public void onResume() {
    super.onResume();
    showGpsDialog();
  }

  @Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    mSignIn.setOnClickListener(new View.OnClickListener() {
      @Override public void onClick(View v) {
        sign(SIGN_IN);
      }
    });

    mSignOut.setOnClickListener(new View.OnClickListener() {
      @Override public void onClick(View v) {
        sign(SIGN_OUT);
      }
    });
    mSignKeep.setOnClickListener(new View.OnClickListener() {
      @Override public void onClick(View v) {
        sign(SIGN_KEEP);
      }
    });

    final Object result = FileUtil.readFromFile(mFile);
    if (result instanceof ArrayList) {
      //noinspection unchecked
      mOriginalList = (ArrayList) result;
      //noinspection unchecked
      mList.addAll(mOriginalList);
    }
    mAdapter =
        new AttendanceListAdapter(getActivity(), mList, this, AttendanceListAdapter.TYPE_USER);

    mListView.setAdapter(mAdapter);
    mAdapter.notifyDataSetChanged();

    mListView.setSelection(mAdapter.getCount());

    mLocationManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);

    //GPS信号强度的监听器
    mLocationListener = new MyLocationListener();
    //检测设备是否含有GPS
    boolean hasGps = mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
    if (!hasGps) {
      showGpsDialog();

      //if (mGpsDialog == null) {
      //    mGpsDialog = new AlertDialog.Builder(getActivity()).setMessage("设备没有GPS")
      //            .setTitle("提示").setCancelable(false).setOnKeyListener(new MyBackKeyListener()).create();
      //}
      //mGpsDialog.show();

    } else {

      mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 1,
          mLocationListener);
    }

    //状态监听
    //第一次定位
    //卫星状态改变
    //ToastUtil.show("卫星状态改变");
    //获取当前状态
    //获取卫星颗数的默认最大值
    //创建一个迭代器保存所有卫星
    //定位启动
    //定位结束
    mGpsListener = new GpsStatus.Listener() {
      public void onGpsStatusChanged(int event) {
        switch (event) {
          //第一次定位
          case GpsStatus.GPS_EVENT_FIRST_FIX:
            //ToastUtil.show("第一次定位成功");
            break;
          //卫星状态改变
          case GpsStatus.GPS_EVENT_SATELLITE_STATUS:
            //ToastUtil.show("卫星状态改变");

            //获取当前状态
            GpsStatus gpsStatus = mLocationManager.getGpsStatus(null);
            //获取卫星颗数的默认最大值
            int maxSatellites = gpsStatus.getMaxSatellites();
            //创建一个迭代器保存所有卫星

            Iterator<GpsSatellite> iters = gpsStatus.getSatellites().iterator();
            int count = 0;
            while (iters.hasNext() && count <= maxSatellites) {
              GpsSatellite s = iters.next();
              if (s.usedInFix()) {
                count++;
              }
            }
            updateRating(count);

            break;
          //定位启动
          case GpsStatus.GPS_EVENT_STARTED:
            //ToastUtil.show("定位启动");
            //mTvLocation.setText("正在定位");
            break;
          //定位结束
          case GpsStatus.GPS_EVENT_STOPPED:

            //ToastUtil.show("定位结束");
            updateLocationHint("定位结束");
            break;
        }
      }
    };

    //绑定监听状态
    mLocationManager.addGpsStatusListener(mGpsListener);
  }

  /**
   * 更新提示信息
   * 同时用于打卡经纬度为空时的提示信息
   *
   * @param s 提示信息
   */
  protected void updateLocationHint(String s) {
    mLocationHint = s;
    mTvGPS.setText(mLocationHint);
  }

  /**
   * 签到打卡数据存储到本地
   *
   * @param type 打卡类型0,1,2
   */
  private void sign(int type) {

    AttendanceDetail item = new AttendanceDetail();
    item.setDate(new Date().getTime());
    item.setCheckTime(new Date().getTime());
    item.setCheckType(type);
    item.setRemark(mRemark.getText().toString().trim());

    if (mLat == 0.0 || mLon == 0.0) {
      ToastUtil.show(mLocationHint);
      return;
    }
    item.setLatitude(mLat + "");//维度
    item.setLongitude(mLon + "");//经度
    //outid用于在地图上显示。
    if (type == SIGN_KEEP) {
      item.setOutId(UUID.randomUUID().toString());
    }
    //noinspection unchecked
    mAdapter.add(item);
    mAdapter.notifyDataSetChanged();
    mRemark.setText("");

    mListView.smoothScrollToPosition(mAdapter.getCount());
  }

  @Override public void click(View v) {
    switch (v.getId()) {
      case R.id.ll_swipe://滑动删除
        int position = (Integer) v.getTag();
        AttendanceDetail item = (AttendanceDetail) mAdapter.getItem(position);
        //noinspection unchecked
        mAdapter.remove(item);
        mAdapter.notifyDataSetChanged();

        break;
    }
  }

  @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    //如果用户已登陆,才显示上传按钮,因为上传接口必须登陆后才能调用.

    if (isLogin) {

      inflater.inflate(R.menu.menu_confirm, menu);
      menu.getItem(0).setTitle("上传");
      menu.getItem(0).setIcon(null);
    }
    super.onCreateOptionsMenu(menu, inflater);
  }

  @Override public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
      case android.R.id.home:
        getActivity().finish();
        break;
      case R.id.menu_item_confirm:
        //ToastUtil.show("上传");
        volleypost();
        break;
    }

    return super.onOptionsItemSelected(item);
  }

  private void volleypost() {

    ArrayList<AtttendanceOutline> outlineList = getOutlineList(mList);
    HashMap<String, String> params = new HashMap<>();
    params.put("regJobNo", CurrentUser.newInstance(getActivity()).getJobNumber());
    params.put("memberCode", CurrentUser.newInstance(getActivity()).getMemberCode());
    params.put("json", new Gson().toJson(outlineList));
    MyUtils.showDialogLoading(getActivity(), R.string.loadingUpload);
    mActivity.volleyPost(ApiConst.getAbsoluteUrl(ApiConst.URL_SIGN_OFFLINE), params,
        new VolleyResponse() {
          @Override public void onVolleyError(VolleyError arg0) {
            MyUtils.dismissDialog();
            ToastUtil.show("离线打卡数据上传失败");
          }

          @Override public void onVolleyResponse(String arg0) throws JSONException {
            MyUtils.dismissDialog();
            //clear();
            Success result = new Gson().fromJson(arg0, Success.class);
            if (result == null) {
              return;
            }
            int successType = result.getResult();
            if (successType == 1) {
              ToastUtil.show("离线打卡数据上传成功");
              clear();
              if (result.getIsValid() != 1) {
                showErrorDialog(result.getMessage());
              }
            } else {
              ToastUtil.show("离线打卡数据上传失败");
            }

            LogUtil.i(arg0);
          }

          /**
           * 清除列表中和设备上的打卡数据
           */
          void clear() {
            mList = new ArrayList<>();
            FileUtil.writeToFile(mList, mFile);
            mAdapter.clear();
            mAdapter.notifyDataSetChanged();
          }
        });
  }

  /**
   * 将打卡数据转换为,离线数据所需的数据集,
   */
  private ArrayList<AtttendanceOutline> getOutlineList(ArrayList<AttendanceDetail> mList) {
    ArrayList<AtttendanceOutline> list = new ArrayList<>();
    for (int i = 0; i < mList.size(); i++) {
      AtttendanceOutline item = new AtttendanceOutline();
      item.setLongitude(mList.get(i).getLongitude());
      item.setLatitude(mList.get(i).getLatitude());
      item.setAttendIdentifyNumber(MyUtils.getDeviceId(getActivity()));
      item.setWifiInfo(MyUtils.getWifiParams(MyUtils.getWifiInfo(getActivity())));
      item.setRemark(mList.get(i).getRemark());
      item.setCheckType(getSignType(mList.get(i).getCheckType()));
      item.setOutId(mList.get(i).getOutId());
      //2016-08-17 08:24:00
      item.setCheckTime(
          DateFormat.format("yyyy-MM-dd HH:mm:ss", mList.get(i).getCheckTime()).toString());
      list.add(item);
    }
    return list;
  }

  protected void showErrorDialog(String message) {
    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()).setMessage(message)
        .setTitle("提示")
        .setPositiveButton("确定", new DialogInterface.OnClickListener() {

          @Override public void onClick(DialogInterface dialog, int which) {
            // Auto-generated method stub

          }
        });
    builder.create().show();
  }

  /**
   * 判断gps是否存在,是否启用,显示gps 的dilaog
   */
  protected void showGpsDialog() {

    //gps是否启用.
    boolean isGpsEnable = mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
    if (isGpsEnable) return;
    //gps未启用
    if (mGpsDialog == null) {
      mGpsDialog = new AlertDialog.Builder(getActivity()).setMessage("GPS未启用,请在设置中打开GPS定位")
          .setOnKeyListener(new MyBackKeyListener())
          .setTitle("提示")
          .setPositiveButton("去启用", new DialogInterface.OnClickListener() {

            @Override public void onClick(DialogInterface dialog, int which) {
              Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
              startActivity(intent);
            }
          })
          .setCancelable(false)
          .create();
    }
    mGpsDialog.show();
  }

  /**
   * 获取签到类型,因为本地是0,1,2,服务端需要的是in,out,keep.转换.
   */

  private String getSignType(int type) {
    String typeStr = "";
    switch (type) {
      case SIGN_IN:
        typeStr = "in";
        break;
      case SIGN_OUT:
        typeStr = "out";
        break;
      case SIGN_KEEP:
        typeStr = "keep";
        break;
    }
    return typeStr;
  }

  /**
   * 更新gps强度信息
   *
   * @param gpsAccuracy 可定位卫星
   */
  private void updateRating(int gpsAccuracy) {
    if (gpsAccuracy == 0) {
      mRatingBar.setRating(0);
      //定位中
      if (mLat == 0.0) {
        updateLocationHint("没有GPS信号");
      }
    } else if (gpsAccuracy < 4) {
      mRatingBar.setRating(1);
      if (mLat == 0.0) {
        updateLocationHint("当前GPS信号差");
      }
    } else {
      mRatingBar.setRating(3);

      if (mLat == 0.0) {
        updateLocationHint("正在定位...");
      }
    }
  }

  @Override public void onDestroy() {
    super.onDestroy();
    mLocationManager.removeGpsStatusListener(mGpsListener);
    mLocationManager.removeUpdates(mLocationListener);
  }

  private class MyBackKeyListener implements DialogInterface.OnKeyListener {

    @Override public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
      if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) {

        getActivity().finish();
      }

      return true;
    }
  }

  private class MyLocationListener implements LocationListener {
    public void onLocationChanged(Location location) {
      if (location == null) return;
      updateLocationHint("定位成功");
      //LogUtil.i("gpsLocation="+location.getLongitude()+","+location.getLatitude());
      double[] item = GPSToGCJUtil.transform(location.getLongitude(), location.getLatitude());
      //LogUtil.i("gpsLocationGaoDe="+item[0]+","+item[1]);
      mLon = item[0];
      mLat = item[1];
    }

    public void onStatusChanged(String provider, int status, Bundle extras) {
      //if (!provider.equals(LocationManager.GPS_PROVIDER)) return;

      //switch (status) {
      //    //GPS状态为可见时
      //    case LocationProvider.AVAILABLE:
      //        ToastUtil.show("当前GPS状态为可见状态");
      //
      //        break;
      //    //GPS状态为服务区外时
      //    case LocationProvider.OUT_OF_SERVICE:
      //        ToastUtil.show("当前GPS状态为服务区外状态");
      //
      //        break;
      //    //GPS状态为暂停服务时
      //    case LocationProvider.TEMPORARILY_UNAVAILABLE:
      //        ToastUtil.show("当前GPS状态为暂停服务状态");
      //
      //
      //        break;
      //}

    }

    public void onProviderEnabled(String provider) {
      if (provider.equals(LocationManager.GPS_PROVIDER)) {
        if (mGpsDialog != null && mGpsDialog.isShowing() && isVisible()) {
          mGpsDialog.dismiss();
        }
      }
      LogUtil.i(provider);
    }

    public void onProviderDisabled(String provider) {
      //LogUtil.i(provider);
      showGpsDialog();
    }
  }
}




